<?php

namespace App\Http\Models;

use Dcat\Admin\Traits\HasDateTimeFormatter;

use Tymon\JWTAuth\Contracts\JWTSubject;
use Illuminate\Notifications\Notifiable;
use Illuminate\Foundation\Auth\User as Authenticatable;

class Member extends Authenticatable implements JWTSubject
{

    use Notifiable;
    use HasDateTimeFormatter;
    protected $table = 'member';

    // protected $appends = ['wx'];

    protected $primaryKey = 'userid';

    public $timestamps = false;
    protected $dateFormat = 'U';
    const CREATED_AT = 'create_time';
    const UPDATED_AT = 'update_time';
    // 用户身份权限
    // 有权限相当于没有  没有权限，相当于全有
    const  PERMISSION = [
        'user' => [
            [
                'name' => '删除企业',
                'action' => 'library/delete',
            ],
            [
                'name' => '修改企业',
                'action' =>  'library/edit',
            ],
            [
                'name' => '档案编辑',
                'action' => 'archives/edit',
            ],
            [
                'name' => '档案删除',
                'action' =>  'archives/delete',
            ],
            [
                'name' => '文献编辑',
                'action' =>  'literature/edit',
            ],
            [
                'name' => '文献删除',
                'action' =>  'literature/delete',
            ],
            [
                'name' => '文献审核',
                'action' =>  'literature/examine',
            ],
        ],
        'sale' => [],
        'admin' => [],
    ];


    protected $fillable = [
        'username',
        'nickname',
        'password',
        'avatar',
        'phone',
        'reg_ip',
        'add_time',
        'status',
        'userTypeId',
        'identity',
    ];

    protected $hidden = [
        'realname',
        'nickname',
        'password',
        'last_login_time',
        'reg_ip',
        'add_time',
        'update_time',
        // 'status',
        'idCard',
        'birth',
        'is_del',
        'age',
        'sign_num',
        'money',
        'sex',
        'integral',
        'credit',
        // 'remarks',
        'parent_id',
        'level',
         'city_id',
        'district_id',
        'province_id',
        'remarks',
    ];

    protected $data;

    protected function setData($key, $value)
    {
        $this->data[$key] = $value;
        array_walk_recursive($this->data, function (&$item, $key) {
            $item = null === $item ? '' : $item;
        });
        return $this->data;
    }

    public static function roles($identity)
    {
        return (array) self::PERMISSION[isset($identity) ? $identity : 'user'];
    }

    /**
     * 高精度 减法
     * @param int|string $uid id
     * @param string $decField 相减的字段
     * @param float|int $dec 减的值
     * @param string $keyField id的字段
     * @param bool $minus 是否可以为负数
     * @param int $acc 精度
     * @return bool
     */
    public static function bcDec($key, $decField, $dec, $keyField = null, $minus = false, $acc = 2)
    {
        if (!is_numeric($dec)) return false;
        $model = new self();
        if ($keyField === null) $keyField = $model->getKey();
        $result = self::where($keyField, $key)->first();
        if (!$result) return false;
        if (!$minus && $result[$decField] < $dec) return false;
        $new = bcsub($result[$decField], $dec, $acc);
        $result->$decField = $new;
        return false !== $result->save();
    }

    /**
     * 高精度 加法
     * @param int|string $uid id
     * @param string $incField 相加的字段
     * @param float|int $inc 加的值
     * @param string $keyField id的字段
     * @param int $acc 精度
     * @return bool
     */
    public static function bcInc($key, $incField, $inc, $keyField = null, $acc = 2)
    {
        if (!is_numeric($inc)) return false;
        $model = new self();
        if ($keyField === null) $keyField = $model->getPk();
        $result = self::where($keyField, $key)->first();
        if (!$result) return false;
        $new = bcadd($result[$incField], $inc, $acc);
        $result->$incField = $new;
        return false !== $result->save();
    }

    public function wx()
    {
        return $this->hasOne(WxloginMember::class, 'user_id', 'userid');
    }

    public function doctor()
    {
        return $this->hasOne(MemberDoctor::class, 'user_id', 'userid');
    }

    /**
     * 获取创建时间
     *
     * @param  string  $value
     * @return string
     */
    public function getCreateTimeAttribute($value)
    {
        return date('Y-m-d H:i:s', $value);
    }

    /**
     * 获取头像
     *
     * @param  string  $value
     * @return string
     */
    public function getAvatarAttribute($value)
    {
        if (empty($value) || $value == config('filesystems.disks.qiniu.domains.https')) {
            return config('filesystems.disks.qiniu.domains.https') . 'default/avatar/' . 'default_avatar.png';
        }
        if ($this->or_url($value)) {
            return $value;
        } else {
            return config('filesystems.disks.qiniu.domains.https') . $value;
        }
    }

    /**
     * 获取修改时间
     *
     * @param  string  $value
     * @return string
     */
    public function getUpdateTimeAttribute($value)
    {
        return date('Y-m-d H:i:s', $value);
    }


    protected static function boot()
    {
        parent::boot();
        static::deleting(function ($user) {
            // $user->wx()->delete();
        });
    }

    public function getJWTIdentifier()
    {
        return $this->getKey();
    }

    /**
     * Return a key value array, containing any custom claims to be added to the JWT.
     *
     * @return array
     */
    public function getJWTCustomClaims()
    {
        return [];
    }


    //判断该手机号是否注册
    public static function checkPhone($phone = '')
    {
        return self::where('username', $phone)->orWhere('phone')->count();
    }

    /**
     * 创建用户
     *
     * @Author hechengwei
     * @email chichiooo@sina.com
     * @DateTime 2022-03-21
     * @param [type] $data
     * @return void
     */
    public static function createMember($data, $model)
    {
        $wx = [
            'openid'    => $data['openId'],
            'nickname'  => $data['nickName'],
            'sex'       => $data['gender'],
            'province'  => $data['province'],
            'city'      => $data['city'],
            'country'   => $data['country'],
            'headimgurl'    => $data['avatarUrl'],
            'addtime'   => time(),
            'user_id'   => $model->userid,
            'unionid'   => $data['unionid'],
        ];
        $model->nickname = $data['nickName'];
        $model->avatar = $data['avatarUrl'] ?? '';
        $model->save();
        return WxloginMember::updateOrCreate(['user_id' => $model->userid], $wx);
    }

    /**
     * 当绑定手机号没有这个手机号码的时候去进行注册
     *
     * @Author hechengwei
     * @email chichiooo@sina.com
     * @DateTime 2022-07-06
     * @param array $payload
     * @return mixed
     */
    public static function weRegister($payload)
    {
        if (self::checkPhone($payload['phone']))  return ['status' => 0, 'msg' => "当前手机号已被注册"];
        $wx_info = WxloginMember::getOne(['openid' => $payload['open_id']]);

        $info = [
            'username' => $payload['phone'],
            'password' => bcrypt(123456),
            'nickname' => $wx_info['nickname'],
            'add_time' => time(),
            'reg_ip' => request()->ip(),
            'userTypeId' => 0,
            'avatar' => $wx_info['headimgurl'],
            'phone' => $payload['phone'],
            'status' => 1,
            'identity' => 'user',
            'json' => null,
        ];

        $member = self::create($info);

        if (!$member) return ['status' => 0, 'msg' => "注册失败"];
        noticeLog('用户注册成功' . json_encode($member));
        return $member;
    }

    protected $casts = [
        'json' => 'array',

    ];


    public function or_url($url)
    {

        if (empty($url)) {
            return true;
        }
        $preg = "/http[s]?:\/\/[\w.]+[\w\/]*[\w.]*\??[\w=&\+\%]*/is";

        if (preg_match($preg, $url)) {

            return true;
        } else {

            return false;
        }
    }
}
